﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SlimDX.Direct3D9;
using SlimDX;

namespace Gype.UI.D3D9
{
    internal class Shader9
    {
        public Shader9(Device dev)
        {
            mVertexCode = ShaderBytecode.Compile(Shaders.UIShader9, "VertexMain", "vs_3_0", ShaderFlags.OptimizationLevel3 | ShaderFlags.Debug);
            mPixelCode = ShaderBytecode.Compile(Shaders.UIShader9, "PixelMain", "ps_3_0", ShaderFlags.OptimizationLevel3 | ShaderFlags.Debug);

            mVertexShader = new VertexShader(dev, mVertexCode);
            mPixelShader = new PixelShader(dev, mPixelCode);

            CreateEffectHandles();
        }

        public void PerformDrawAction(Action action)
        {
            var dev = mVertexShader.Device;
            dev.VertexShader = mVertexShader;
            dev.PixelShader = mPixelShader;

            action();

            dev.VertexShader = null;
            dev.PixelShader = null;
        }

        public void SetUseTexture(bool useTexture)
        {
            var dev = mVertexShader.Device;
            dev.SetPixelShaderConstant(mUseTexture.RegisterIndex, new bool[] { useTexture });
        }

        public void SetOrthoMatrix(Matrix matrix)
        {
            var dev = mVertexShader.Device;
            dev.SetVertexShaderConstant(mMatrixParam.RegisterIndex, matrix);
        }

        private void CreateEffectHandles()
        {
            mMatrixParam = mVertexCode.ConstantTable.GetConstantDescription(mVertexCode.ConstantTable.GetConstant(null, 0));

            var numPixelConstants = mPixelCode.ConstantTable.Description.Constants;
            for (int i = 0; i < numPixelConstants; ++i)
            {
                var constant = mPixelCode.ConstantTable.GetConstant(null, i);

                var desc = mPixelCode.ConstantTable.GetConstantDescription(constant);
                if (desc.Name == "useTexture")
                    mUseTexture = desc;
            }
        }

        private VertexShader mVertexShader;
        private PixelShader mPixelShader;
        private ConstantDescription mUseTexture;
        private ConstantDescription mMatrixParam;
        private ShaderBytecode mVertexCode, mPixelCode;
    }
}
